I'm a little confused as to what you mean by calling that function. Where would I call that function? And what is the requestItentifier in that function?
Post
Replies
Boosts
Views
Activity
class LocalNotificationManager: ObservableObject {
@Environment(\.managedObjectContext) private var viewContext
var meetings: Item?
var notifications = [Notification]()
init() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if granted == true && error == nil {
print("Notifications permitted")
} else {
print("Notifications not permitted")
}
}
}
func sendNotification(title: String, subtitle: String?, body: String, time: Date, id: UUID, repeatPattern: String) {
let content = UNMutableNotificationContent()
content.title = title
if let subtitle = subtitle {
content.subtitle = subtitle
}
content.body = body
content.sound = UNNotificationSound.default
let triggerDate = time - 5 * 60
if repeatPattern == "Daily" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "Weekly" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.timeZone, .weekday, .hour, .minute, .second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "Monthly" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.timeZone, .weekOfMonth, .weekday, .hour, .minute, .second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "None" {
let trigger = UNCalendarNotificationTrigger(
dateMatching: Calendar.current.dateComponents([.timeZone, .year, .month, .day, .hour, .minute], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
let center = UNUserNotificationCenter.current()
center.getPendingNotificationRequests(completionHandler: { requests in
for request in requests {
print(request)
}
})
}
}
func sendNotification(title: String, subtitle: String?, body: String, time: Date, id: UUID, repeatPattern: String) {
let content = UNMutableNotificationContent()
content.title = title
if let subtitle = subtitle {
content.subtitle = subtitle
}
content.body = body
content.sound = UNNotificationSound.default
let triggerDate = time - 5 * 60
if repeatPattern == "Daily" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "Weekly" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.timeZone, .weekday, .hour, .minute, .second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "Monthly" {
let trigger = UNCalendarNotificationTrigger(dateMatching: Calendar.current.dateComponents([.timeZone, .weekOfMonth, .weekday, .hour, .minute, .second], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
} else if repeatPattern == "None" {
let trigger = UNCalendarNotificationTrigger(
dateMatching: Calendar.current.dateComponents([.timeZone, .year, .month, .day, .hour, .minute], from: triggerDate), repeats: true)
let request = UNNotificationRequest(identifier: "\(id)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
}
Calling the function in the add meeting modal :
self.notificationManager.sendNotification(title: "Upcoming Meeting", subtitle: nil, body: "\(meetingName) will start in 5 minutes. Tap for meeting information.", time: newMeeting.time!, id: newMeeting.id!, repeatPattern: "\(repeats)")
print("Scheduled repeating notification.")
I think your second idea is what I might use, because of this: each event a user creates has a UUID stored in Core Data. The notification identifier is the same as the UUID, so when a user deletes an event, it's really simple to delete the pending notification request. Using your method of creating a new notification when the current one fires, can I recycle the same UUID and keep using that UUID for the future notifications?
Also, I'm not familiar with how to schedule a new notification when the existing one fires. What function is that?
Hey Claude,
Thanks so much for all your help. I'm actually really new to coding, so I have no idea of how to implement your suggestions above. Is there any way you could help me with the code?
Thanks so much!
Thank you for your reply. Given a start date and a repeat pattern (every week, day, etc.), how do I transform that into an array for CoreData?
Thank you for taking the time to do that. As you suggested, I will try to merge some code with a new project.
Thank you. It worked the first time after I deleted the app from my actual device and ran the project, but after that, the button stopped working, if you'll believe it.
Seems like it might have been an error with Xcode. I just tried using the simulator, and it works fine. I was using my personal device and deleting the app each time. That might have something to do with the app storage property, I don't know. Do you know if deleting an app from the device actually resets the app storage properties? The 'Welcome to Meetings' still shows up, but the 'get started' button doesn't work.
Source code here. - https://github.com/bwhoman/project.git (Github) To recreate, just run the program and try to click "Get Started"
Files are in 'IntroductionView.swift' and 'ContentView.swift' Find the code for showing the modal on lines 106 and 208 of ContentView.
Oh, you want to run it. Let me give you the complete source code. Here - https://github.com/bwhoman/deercat.git
Yes. It's content view and the notifications file.
Github link - https://github.com/bwhoman/meetingsapp.git
Code for content view:
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
entity: Item.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Item.time, ascending: true)],
animation: .default)
private var items: FetchedResultsItem
NavigationView {
List {
Section(header:
Text("One-Time Meetings")
.textCase(nil)
.font(.headline)
.onAppear {
checkForUpdate()
}
) {
ForEach(items, id: \.self) { item in
OneTimeRow(meeting: item)
}
.onDelete(perform: deleteItems, removeSingleNotification(meetingID: "\(item.meetingLink)"))
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
print("There was an error deleting items")
}
}
}
private func removeSingleNotification(meetingID: String) {
notificationManager.removePendingNotificationRequests(meetingID: meetingID)
print("Deleted notification scheduled for meeting with identifier \(meetingID)")
}
Items is defined in a fetch request at the top of this view.
@FetchRequest(
entity: Item.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Item.time, ascending: true)],
animation: .default)
private var items: FetchedResultsItem